package com.pokermind.dse.util;

import com.pokermind.model.dto.ActionRequest;
import com.pokermind.model.dto.CreateHandRequest;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 德州扑克手牌自动验证器
 * 
 * 功能：
 * - 自动计算期望的底池大小
 * - 验证筹码变化是否正确
 * - 检查行动序列逻辑
 * - 生成验证报告
 */
public class PokerHandValidator {
    
    private final List<ActionRequest> actions = new ArrayList<>();
    private final CreateHandRequest initialHand;
    private BigDecimal currentPot;
    private int totalActions = 0;
    
    public PokerHandValidator(CreateHandRequest createRequest) {
        this.initialHand = createRequest;
        this.currentPot = calculateInitialPot(createRequest);
    }
    
    /**
     * 添加行动并验证
     */
    public ValidationResult addAction(ActionRequest action) {
        actions.add(action);
        totalActions++;
        
        ValidationResult result = new ValidationResult();
        
        // 验证1：底池计算
        BigDecimal expectedPot = calculateExpectedPot(action);
        if (!expectedPot.equals(action.getPotAfter())) {
            result.addError(String.format("底池计算错误 - 期望: %s, 实际: %s", 
                expectedPot, action.getPotAfter()));
        }
        
        // 验证2：筹码变化  
        BigDecimal expectedStack = calculateExpectedStack(action);
        if (expectedStack != null && !expectedStack.equals(action.getStackAfter())) {
            result.addError(String.format("筹码计算错误 - 期望: %s, 实际: %s", 
                expectedStack, action.getStackAfter()));
        }
        
        // 验证3：行动类型合理性
        if (!isValidActionType(action)) {
            result.addError("无效的行动类型: " + action.getActionType());
        }
        
        // 更新当前状态
        currentPot = action.getPotAfter();
        
        return result;
    }
    
    /**
     * 生成完整验证报告
     */
    public String generateReport() {
        StringBuilder report = new StringBuilder();
        report.append("🧾 德州扑克手牌验证报告\n");
        report.append("================================================================================\n");
        report.append(String.format("手牌ID: %s\n", initialHand.getHandId()));
        report.append(String.format("初始底池: %s (SB: %s + BB: %s)\n", 
            calculateInitialPot(initialHand), initialHand.getSmallBlind(), initialHand.getBigBlind()));
        report.append(String.format("总行动数: %d\n", totalActions));
        report.append(String.format("最终底池: %s\n", currentPot));
        report.append("\n📋 行动序列验证:\n");
        
        for (int i = 0; i < actions.size(); i++) {
            ActionRequest action = actions.get(i);
            report.append(String.format("%d. 玩家:%s %s %s -> 底池:%s 筹码:%s\n",
                i + 1, action.getPlayerId(),
                action.getActionType(), action.getAmount(), action.getPotAfter(), action.getStackAfter()));
        }
        
        report.append("\n💰 资金流向验证:\n");
        BigDecimal totalInvested = calculateTotalInvestment();
        report.append(String.format("总投入: %s\n", totalInvested));
        report.append(String.format("最终底池: %s\n", currentPot));
        report.append(String.format("匹配状态: %s\n", 
            totalInvested.equals(currentPot) ? "✅ 正确" : "❌ 错误"));
        
        return report.toString();
    }
    
    // 内部计算方法
    private BigDecimal calculateInitialPot(CreateHandRequest request) {
        return request.getSmallBlind().add(request.getBigBlind()).add(
            request.getAnte().multiply(new BigDecimal(request.getPlayers().size())));
    }
    
    private BigDecimal calculateExpectedPot(ActionRequest action) {
        if (action.getActionType().equals("fold") || action.getActionType().equals("check")) {
            return currentPot;  // 底池不变
        } else if (action.getActionType().equals("call") || 
                   action.getActionType().equals("bet") || 
                   action.getActionType().equals("raise")) {
            return currentPot.add(action.getAmount());  // 增加投注金额
        }
        return currentPot;
    }
    
    private BigDecimal calculateExpectedStack(ActionRequest action) {
        // 这里简化实现，实际项目中需要跟踪每个玩家的筹码
        // 仅作为示例验证逻辑
        return null;  
    }
    
    private boolean isValidActionType(ActionRequest action) {
        String type = action.getActionType();
        return type.equals("fold") || type.equals("check") || type.equals("call") || 
               type.equals("bet") || type.equals("raise");
    }
    
    private BigDecimal calculateTotalInvestment() {
        return actions.stream()
            .map(ActionRequest::getAmount)
            .reduce(calculateInitialPot(initialHand), BigDecimal::add);
    }
    
    /**
     * 验证结果类
     */
    public static class ValidationResult {
        private final List<String> errors = new ArrayList<>();
        private final List<String> warnings = new ArrayList<>();
        
        public void addError(String error) {
            errors.add(error);
        }
        
        public void addWarning(String warning) {
            warnings.add(warning);
        }
        
        public boolean isValid() {
            return errors.isEmpty();
        }
        
        public List<String> getErrors() {
            return new ArrayList<>(errors);
        }
        
        public List<String> getWarnings() {
            return new ArrayList<>(warnings);
        }
        
        @Override
        public String toString() {
            if (isValid() && warnings.isEmpty()) {
                return "✅ 验证通过";
            }
            
            StringBuilder sb = new StringBuilder();
            if (!errors.isEmpty()) {
                sb.append("❌ 错误: ").append(String.join(", ", errors));
            }
            if (!warnings.isEmpty()) {
                if (sb.length() > 0) sb.append("\n");
                sb.append("⚠️  警告: ").append(String.join(", ", warnings));
            }
            return sb.toString();
        }
    }
}





